﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.ExpressionParsing;
using Common.Constants;

namespace Service.BusinessLogic
{
    public class ParameterResolver
    {
        protected IDictionary<String, ParameterDescription> Parameters { get; set; }

        public ParameterResolver(List<ParameterDescription> parameters)
        {
            Parameters = new Dictionary<String, ParameterDescription>();
            parameters.ForEach(param => Parameters.Add(param.Name, param));
        }

        public List<ParameterDescription> Resolve()
        {
            Int32 resolvingParametersCount = Parameters.Values.Where(p => !p.IsResolve).Count();
            
            for(int i = 0; i < resolvingParametersCount; i++)
            {
                foreach (String name in Parameters.Keys)
                {
                    ParameterDescription pd = Parameters[name];
                    if (pd.IsResolve)
                        continue;
                    
                    Object value = null;
                    Boolean isResolved = false;

                    ResolveParameter(pd, out isResolved, out value);

                    if (isResolved)
                    {
                        pd.IsResolve = true;
                        pd.ParameterValue = value;
                    }
                }

                if (Parameters.Values.Where(p => !p.IsResolve).Count() == 0)
                    break;
            }

            return Parameters.Values.ToList();
        }

        private void ResolveParameter(ParameterDescription pd, out Boolean isResolved, out Object value)
        {
            isResolved = false;
            value = null;

            try
            {
                Expression expr = new Expression(pd.Expression);
                
                //BusinessLogicCommonVisitorExtension commonExt = new BusinessLogicCommonVisitorExtension(CurrentBusinessEntity, TimeStamp);
                //expr.ExtensionManager.AddExtension(commonExt);

                Dictionary<String, String> namedParameters = new Dictionary<String, String>();
                foreach(String name in Parameters.Keys)
                    if(Parameters[name].IsResolve)
                        namedParameters.Add(name, PutParameter(Parameters[name]));
                expr.ExternalParams = namedParameters;
                value = expr.Evaluate();
                isResolved = true;
            }
            catch (Exception ex)
            {
                value = null;
                isResolved = false;
            }
        }

        protected String PutParameter(ParameterDescription param)
        {
            if (param.Type == ParameterDataType.Boolean)
                return param.ParameterValue.ToString().ToLower() == "true" ? "true" : "false";
            else if (param.Type == ParameterDataType.DateTime)
                return "#" + param.ParameterValue.ToString() + "#";
            else if (param.Type == ParameterDataType.Decimal)
                return param.ParameterValue.ToString();
            else if (param.Type == ParameterDataType.Intager)
                return param.ParameterValue.ToString();
            else if (param.Type == ParameterDataType.String)
                return "'" + param.ParameterValue.ToString() + "'";
            else
                return param.ParameterValue.ToString();
        }
    }

}
